<?php

/**
 * 充值
 */
class Api_Charge extends PhalApi_Api
{
	
	public function getRules()
	{
		return array(
			'getAliOrder'             => array(
				'uid'      => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
				'token'    => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户Token'),
				'changeid' => array('name' => 'changeid', 'type' => 'int', 'require' => true, 'desc' => '充值规则ID'),
				'coin'     => array('name' => 'coin', 'type' => 'string', 'require' => true, 'desc' => '钻石'),
				'money'    => array('name' => 'money', 'type' => 'string', 'require' => true, 'desc' => '充值金额'),
			),
			'getWxOrder'              => array(
				'uid'      => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
				'token'    => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户Token'),
				'changeid' => array('name' => 'changeid', 'type' => 'string', 'require' => true, 'desc' => '充值规则ID'),
				'coin'     => array('name' => 'coin', 'type' => 'string', 'require' => true, 'desc' => '钻石'),
				'money'    => array('name' => 'money', 'type' => 'string', 'require' => true, 'desc' => '充值金额'),
			),
			'getIosOrder'             => array(
				'uid'      => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
				'token'    => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户Token'),
				'changeid' => array('name' => 'changeid', 'type' => 'string', 'require' => true, 'desc' => '充值规则ID'),
				'coin'     => array('name' => 'coin', 'type' => 'string', 'require' => true, 'desc' => '钻石'),
				'money'    => array('name' => 'money', 'type' => 'string', 'require' => true, 'desc' => '充值金额'),
			),
			'getWxMiniOrder'          => array(
				'uid'      => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
				'chargeid' => array('name' => 'chargeid', 'type' => 'string', 'require' => true, 'desc' => '充值规则ID'),
				'coin'     => array('name' => 'coin', 'type' => 'string', 'require' => true, 'desc' => '钻石'),
				'money'    => array('name' => 'money', 'type' => 'string', 'require' => true, 'desc' => '充值金额'),
				'openid'   => array('name' => 'openid', 'type' => 'string', 'require' => true, 'desc' => '用户在商户appid下的唯一标识'),
			),
			'getPaypalOrder'          => array(
				'uid'      => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
				'token'    => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户Token'),
				'changeid' => array('name' => 'changeid', 'type' => 'int', 'require' => true, 'desc' => '充值规则ID'),
				'coin'     => array('name' => 'coin', 'type' => 'string', 'require' => true, 'desc' => '钻石'),
				'money'    => array('name' => 'money', 'type' => 'string', 'require' => true, 'desc' => '充值金额'),
			),
			'getBraintreePaypalOrder' => array(
				'uid'      => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
				'token'    => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户Token'),
				'changeid' => array('name' => 'changeid', 'type' => 'int', 'require' => true, 'desc' => '充值规则ID'),
				'coin'     => array('name' => 'coin', 'type' => 'string', 'require' => true, 'desc' => '钻石'),
				'money'    => array('name' => 'money', 'type' => 'string', 'require' => true, 'desc' => '充值金额'),
			),
			'getFirstChargeRules'     => array(
				'uid'   => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
				'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户Token'),
			),
		);
	}
	
	#####################################################################################################################################
	## 各种支付操作
	
	/**
	 * 微信支付获取订单号
	 * @desc 用于 微信支付获取订单号
	 * @return int code 操作码，0表示成功
	 * @return array info
	 * @return string info[0] 支付信息
	 * @return string msg 提示信息
	 */
	public function getWxOrder()
	{
		$uid      = checkNull($this->uid);
		$token    = checkNull($this->token);
		$changeid = checkNull($this->changeid);
		$coin     = checkNull($this->coin);
		$money    = checkNull($this->money);
		
		$checkToken = checkToken($uid, $token);
		if($checkToken == 700){
			return $this->fail('您的登陆状态失效，请重新登陆！', $checkToken);
		}
		
		$orderid = $this->getOrderid($uid);
		$type    = 2;
		if($coin == 0){
			return $this->fail('信息错误', 1002);
		}
		
		$configpri = getConfigPri();
		$configpub = getConfigPub();
		//配置参数检测
		if($configpri['wx_appid'] == "" || $configpri['wx_mchid'] == "" || $configpri['wx_key'] == ""){
			return $this->fail('微信未配置', 1002);
		}
		
		$orderinfo = array("uid" => $uid, "touid" => $uid, "money" => $money, "coin" => $coin, "orderno" => $orderid, "type" => $type, "status" => 0, "addtime" => time());
		$domain    = new Domain_Charge();
		$info      = $domain->getOrderId($changeid, $orderinfo);
		if($info == 1003){
			return $this->fail('订单信息有误，请重新提交', 1003);
		} elseif(!$info){
			return $this->fail('订单生成失败', 1001);
		}
		
		$noceStr  = md5(rand(100, 1000).time());//获取随机字符串
		$time     = time();
		$paramarr = array(
			"appid"        => $configpri['wx_appid'],
			"body"         => "充值{$coin}虚拟币",
			"mch_id"       => $configpri['wx_mchid'],
			"nonce_str"    => $noceStr,
			"notify_url"   => $configpub['site'].'/appapi/pay/notify_wx',
			"out_trade_no" => $orderid,
			"total_fee"    => $money * 100,
			"trade_type"   => "APP",
		);
		
		$sign             = $this->sign($paramarr, $configpri['wx_key']);//生成签名
		$paramarr['sign'] = $sign;
		$paramXml         = "<xml>";
		foreach($paramarr as $k => $v){
			$paramXml .= "<".$k.">".$v."</".$k.">";
		}
		$paramXml .= "</xml>";
		
		$ch = curl_init();
		@curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查  
		@curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);  // 从证书中检查SSL加密算法是否存在  
		@curl_setopt($ch, CURLOPT_URL, "https://api.mch.weixin.qq.com/pay/unifiedorder");
		@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		@curl_setopt($ch, CURLOPT_POST, 1);
		@curl_setopt($ch, CURLOPT_POSTFIELDS, $paramXml);
		@$resultXmlStr = curl_exec($ch);
		if(curl_errno($ch)){
			//print curl_error($ch);
			file_put_contents(API_ROOT.'/../log/phalapi/charge_wxpay_'.date('Y-m-d').'.txt', date('y-m-d H:i:s').' 提交参数信息 ch:'.json_encode(curl_error($ch))."\r\n\r\n", FILE_APPEND);
		}
		
		curl_close($ch);
		$result2 = $this->xmlToArray($resultXmlStr);
		if($result2['return_code'] == 'FAIL'){
			return $this->fail($result2['return_msg'], 1005);
		}
		
		$time2             = time();
		$prepayid          = $result2['prepay_id'];
		$sign              = "";
		$noceStr           = md5(rand(100, 1000).time());//获取随机字符串
		$paramarr2         = array("appid" => $configpri['wx_appid'], "noncestr" => $noceStr, "package" => "Sign=WXPay", "partnerid" => $configpri['wx_mchid'], "prepayid" => $prepayid, "timestamp" => $time2);
		$paramarr2["sign"] = $this->sign($paramarr2, $configpri['wx_key']);//生成签名
		
		return $this->success(['0' => $paramarr2]);
	}

	
	/**
	 * 微信小程序支付获取订单号
	 * @desc 用于 微信小程序支付获取订单号
	 * @return int code 操作码，0表示成功
	 * @return array info
	 * @return string info[0] 支付信息
	 * @return string msg 提示信息
	 */
	public function getWxMiniOrder()
	{
		$uid      = checkNull($this->uid);
		$chargeid = checkNull($this->chargeid);
		$coin     = checkNull($this->coin);
		$money    = checkNull($this->money);
		$openid   = checkNull($this->openid);
		
		$orderid = $this->getOrderid($uid);
		$type    = 4;
		if($coin == 0){
			return $this->fail('信息错误', 1002);
		}
		
		$configpri = getConfigPri();
		$configpub = getConfigPub();
		//配置参数检测
		if($configpri['wx_mini_appid'] == "" || $configpri['wx_mini_mchid'] == "" || $configpri['wx_mini_key'] == ""){
			return $this->fail('微信小程序支付未配置', 1002);
		}
		if(!$openid){
			return $this->fail('缺少必要参数openid', 1002);
		}
		
		$orderinfo = array("uid" => $uid, "touid" => $uid, "money" => $money, "coin" => $coin, "orderno" => $orderid, "type" => $type, "status" => 0, "addtime" => time());
		$domain    = new Domain_Charge();
		$info      = $domain->getOrderId($chargeid, $orderinfo);
		if($info == 1003){
			return $this->fail('订单信息有误，请重新提交', 1003);
		} elseif(!$info){
			return $this->fail('订单生成失败', 1001);
		}
		
		$noceStr  = md5(rand(100, 1000).time());//获取随机字符串
		$time     = time();
		$paramarr = array(
			"appid"            => $configpri['wx_mini_appid'],
			"body"             => "充值{$coin}虚拟币",
			"mch_id"           => $configpri['wx_mini_mchid'],
			"nonce_str"        => $noceStr,
			"notify_url"       => $configpub['site'].'/appapi/pay/notify_wx_mini',
			"openid"           => $openid,
			"out_trade_no"     => $orderid,
			"spbill_create_ip" => $_SERVER["REMOTE_ADDR"],
			"total_fee"        => $money * 100,
			"trade_type"       => "JSAPI",
		);
		
		$sign = $this->sign($paramarr, $configpri['wx_mini_key']);//生成签名
		
		$paramarr['sign'] = $sign;
		/*var_dump($paramarr);
		die;*/
		
		$paramXml = "<xml>";
		foreach($paramarr as $k => $v){
			$paramXml .= "<".$k.">".$v."</".$k.">";
		}
		$paramXml .= "</xml>";
		
		/*var_dump($paramXml);
		die;*/
		
		$ch = curl_init();
		@curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
		@curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);  // 从证书中检查SSL加密算法是否存在
		@curl_setopt($ch, CURLOPT_URL, "https://api.mch.weixin.qq.com/pay/unifiedorder");
		@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		@curl_setopt($ch, CURLOPT_POST, 1);
		@curl_setopt($ch, CURLOPT_POSTFIELDS, $paramXml);
		@$resultXmlStr = curl_exec($ch);
		if(curl_errno($ch)){
			//print curl_error($ch);
			file_put_contents(API_ROOT.'/../log/phalapi/charge_wxmini_pay_'.date('Y-m-d').'.txt', date('y-m-d H:i:s').' 提交参数信息 ch:'.json_encode(curl_error($ch))."\r\n\r\n", FILE_APPEND);
		}
		curl_close($ch);
		
		$result2 = $this->xmlToArray($resultXmlStr);
		if($result2['return_code'] == 'FAIL'){
			return $this->fail($result2['return_msg'], 1005);
		}
		
		$time2    = time();
		$prepayid = $result2['prepay_id'];
		$sign     = "";
		$noceStr  = md5(rand(100, 1000).time());//获取随机字符串
		//注意参数大小写
		$paramarr2         = array(
			"appId"     => $configpri['wx_mini_appid'],
			"timeStamp" => $time2,
			"nonceStr"  => $noceStr,
			"package"   => "prepay_id=".$prepayid,
			"signType"  => "MD5",
		);
		$paramarr2["sign"] = $this->sign($paramarr2, $configpri['wx_mini_key']);//生成签名
		
		return $this->success(['0' => $paramarr2]);
	}
	
	#####################################################################################################################################
	
	/**
	 * 支付宝支付获取订单号
	 * @desc 用于支付宝支付获取订单号
	 * @return int code 操作码，0表示成功
	 * @return array info
	 * @return string info[0].orderid 订单号
	 * @return string msg 提示信息
	 */
	public function getAliOrder()
	{
		$rs       = array('code' => 0, 'msg' => '', 'info' => array());
		$uid      = checkNull($this->uid);
		$token    = checkNull($this->token);
		$changeid = checkNull($this->changeid);
		$coin     = checkNull($this->coin);
		$money    = checkNull($this->money);
		
		$checkToken = checkToken($uid, $token);
		if($checkToken == 700){
			return $this->fail('您的登陆状态失效，请重新登陆！', $checkToken);
		}
		
		$configpri = getConfigPri();
		if(!$configpri['aliapp_partner'] || !$configpri['aliapp_seller_id'] || !$configpri['aliapp_key_android'] || !$configpri['aliapp_key_ios']){
			return $this->fail('支付宝未配置！', 1001);
		}
		
		$orderid = $this->getOrderid($uid);
		$type    = 1;
		if($coin == 0){
			return $this->fail('信息错误', 1002);
		}
		
		$orderinfo = array("uid" => $uid, "touid" => $uid, "money" => $money, "coin" => $coin, "orderno" => $orderid, "type" => $type, "status" => 0, "addtime" => time());
		$domain    = new Domain_Charge();
		$info      = $domain->getOrderId($changeid, $orderinfo);
		if($info == 1003){
			$code = 1003;
			$msg  = '订单信息有误，请重新提交';
		} elseif(!$info){
			$code = 1001;
			$msg  = '订单生成失败';
		}
		
		return $this->fail($msg, $code, ['0' => ['orderid' => $orderid]]);
	}
	
	
	/**
	 * 苹果支付获取订单号
	 * @desc 用于苹果支付获取订单号
	 * @return int code 操作码，0表示成功
	 * @return array info
	 * @return string info[0].orderid 订单号
	 * @return string msg 提示信息
	 */
	public function getIosOrder()
	{
		$rs = array('code' => 0, 'msg' => '', 'info' => array());
		
		$uid      = checkNull($this->uid);
		$token    = checkNull($this->token);
		$changeid = checkNull($this->changeid);
		$coin     = checkNull($this->coin);
		$money    = checkNull($this->money);
		
		$checkToken = checkToken($uid, $token);
		if($checkToken == 700){
			return $this->fail('您的登陆状态失效，请重新登陆！', $checkToken);
		}
		
		$orderid = $this->getOrderid($uid);
		$type    = 3;
		if($coin == 0){
			return $this->fail('信息错误', 1002);
		}
		
		$configpri = getConfigPri();
		$orderinfo = array(
			"uid"     => $uid,
			"touid"   => $uid,
			"money"   => $money,
			"coin"    => $coin,
			"orderno" => $orderid,
			"type"    => $type,
			"status"  => 0,
			"addtime" => time(),
		);
		
		$domain = new Domain_Charge();
		$info   = $domain->getOrderId($changeid, $orderinfo);
		if($info == 1003){
			$code = 1003;
			$msg  = '订单信息有误，请重新提交';
		} elseif(!$info){
			$code = 1001;
			$msg  = '订单生成失败';
		}
		
		return $this->fail($msg, $code, ['0' => ['orderid' => $orderid]]);
	}

	
	/**
	 * paypal支付获取订单号
	 * @desc 用于贝宝支付获取订单号
	 * @return int code 操作码，0表示成功
	 * @return array info
	 * @return string info[0].orderid 订单号
	 * @return string msg 提示信息
	 */
	private function getPaypalOrderBF()
	{
		$uid      = checkNull($this->uid);
		$token    = checkNull($this->token);
		$changeid = checkNull($this->changeid);
		$coin     = checkNull($this->coin);
		$money    = checkNull($this->money);
		
		$configpri = getConfigPri();
		if($configpri['paypal_sandbox'] == 0){
			if(!$configpri['sandbox_clientid']){
				return $this->fail('Paypal未配置', 1001);
			}
		} else{
			if(!$configpri['product_clientid']){
				return $this->fail('Paypal未配置', 1001);
			}
		}
		
		$orderid = $this->getOrderid($uid);
		$type    = 5;
		if($coin == 0){
			return $this->fail('信息错误', 1002);
		}
		
		$orderinfo = array(
			"uid"     => $uid,
			"touid"   => $uid,
			"money"   => $money,
			"coin"    => $coin,
			"orderno" => $orderid,
			"type"    => $type,
			"status"  => 0,
			"addtime" => time(),
		);
		$domain    = new Domain_Charge();
		$info      = $domain->getOrderId($changeid, $orderinfo);
		if($info == 1003){
			$code = 1003;
			$msg  = '订单信息有误，请重新提交';
		} elseif(!$info){
			$code = 1001;
			$msg  = '订单生成失败';
		}
		
		$paypal = [
			'paypal_sandbox'   => $configpri['paypal_sandbox'],//支付模式：0：沙盒支付；1：生产支付
			'sandbox_clientid' => $configpri['sandbox_clientid'],//沙盒客户端ID
			'product_clientid' => $configpri['product_clientid'],//生产客户端ID
		];
		
		return $this->fail($msg, $code, ['0' => [$paypal, 'orderid' => $orderid,]]);
	}
	
	
	/**
	 * Braintree绑定Paypal支付获取订单号
	 * @desc 用于Braintree绑定Paypal支付获取订单号
	 * @return int code 操作码，0表示成功
	 * @return array info
	 * @return string info[0].orderid 订单号
	 * @return string msg 提示信息
	 */
	public function getBraintreePaypalOrder()
	{
		$uid      = checkNull($this->uid);
		$token    = checkNull($this->token);
		$changeid = checkNull($this->changeid);
		$coin     = checkNull($this->coin);
		$money    = checkNull($this->money);
		
		$checkToken = checkToken($uid, $token);
		if($checkToken == 700){
			return $this->fail('您的登陆状态失效，请重新登陆！', $checkToken);
		}
		
		$configpri   = getConfigPri();
		$environment = $configpri['braintree_paypal_environment'];
		
		$merchantId = '';
		$publicKey  = '';
		$privateKey = '';
		if($environment == 0){ //沙盒
			$merchantId = $configpri['braintree_merchantid_sandbox'];
			$publicKey  = $configpri['braintree_publickey_sandbox'];
			$privateKey = $configpri['braintree_privatekey_sandbox'];
		} else{ //生产
			$merchantId = $configpri['braintree_merchantid_product'];
			$publicKey  = $configpri['braintree_publickey_product'];
			$privateKey = $configpri['braintree_privatekey_product'];
		}
		if(!$merchantId || !$publicKey || !$privateKey){
			return $this->fail('BraintreePaypal未配置', 1001);
		}
		
		$orderid = $this->getOrderid($uid);
		$type    = 6;
		if($coin == 0){
			return $this->fail('信息错误', 1002);
		}
		
		$orderinfo = array(
			"uid"     => $uid,
			"touid"   => $uid,
			"money"   => $money,
			"coin"    => $coin,
			"orderno" => $orderid,
			"type"    => $type,
			"status"  => 0,
			"addtime" => time(),
		);
		
		$domain = new Domain_Charge();
		$info   = $domain->getOrderId($changeid, $orderinfo);
		if($info == 1003){
			$code = 1003;
			$msg  = '订单信息有误，请重新提交';
		} elseif(!$info){
			$code = 1001;
			$msg  = '订单生成失败';
		}
		
		return $this->fail($msg, $code, ['0' => ['orderid' => $orderid,]]);
	}
	
	/**
	 * 获取首充充值规则列表
	 * @desc 获取首充充值规则列表
	 * @return int code 状态码,0表示成功
	 * @return string msg 提示信息
	 * @return array info 返回信息
	 * @return int info[0]['has_used'] 首充机会是否已用完 0 否 1 是
	 * @return int info[0]['list'] 返回充值规则
	 * @return int info[0]['list'][]['id'] 返回充值规则ID
	 * @return int info[0]['list'][]['title'] 返回充值规则名称
	 * @return int info[0]['list'][]['money'] 返回充值规则金额
	 * @return int info[0]['list'][]['coin'] 返回充值规则钻石数
	 * @return array info[0]['list'][]['list'] 返回充值规则项目列表
	 * @return string info[0]['list'][]['list'][]['name'] 返回充值规则项目列表项的名称
	 * @return string info[0]['list'][]['list'][]['count'] 返回充值规则项目列表项的数量
	 * @return string info[0]['list'][]['list'][]['thumb'] 返回充值规则项目列表项的数量
	 */
	public function getFirstChargeRules()
	{
		$uid        = checkNull($this->uid);
		$token      = checkNull($this->token);
		$checkToken = checkToken($uid, $token);
		if($checkToken == 700){
			return $this->fail('您的登陆状态失效，请重新登陆！', $checkToken);
		}
		
		$domain    = new Domain_Charge();
		$res       = $domain->getFirstChargeRules();
		$configpri = getConfigPri();
		$switch    = $configpri['firstcharge_repeatedly'];
		$has_used  = '0';
		if(!$switch){
			$firstcharge_used = checkUserFirstCharge($uid);
			if($firstcharge_used){
				$has_used = '1';
			}
		}
		
		$info = ['list' => $res, 'has_used' => $has_used];
		
		return $this->success(['0' => $info]);
	}
	
	#####################################################################################################################################
	/**
	 * sign拼装获取
	 */
	protected function sign($param, $key)
	{
		$sign = "";
		ksort($param);
		foreach($param as $k => $v){
			$sign .= $k."=".$v."&";
		}
		
		$sign .= "key=".$key;
		$sign = strtoupper(md5($sign));
		
		return $sign;
	}
	
	/**
	 * xml转为数组
	 */
	protected function xmlToArray($xmlStr)
	{
		$msg     = array();
		$postStr = $xmlStr;
		$msg     = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
		
		return $msg;
	}
	
	
	/* 获取订单号 */
	protected function getOrderid($uid)
	{
		$orderid = $uid.'_'.date('YmdHis').rand(100, 999);
		
		return $orderid;
	}
	
}
